from project.apps.user import user_blueprint
from flask_restful import Resource, Api
from flask import current_app
from random import randint
from datetime import datetime
from project import db
from project.models.user import User
from project.utils.user import login_token, check_user_token
from flask import request
from flask import g
from project.models.news import UserChannel

user_api = Api(user_blueprint)

from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps


@user_api.representation('application/json')
def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

    if 'message' not in data:
        data={
            'message':'ok',
            'data':data
        }

    settings = current_app.config.get('RESTFUL_JSON', {})

    # If we're in debug mode, and the indent is not set, we set it to a
    # reasonable value here.  Note that this won't override any existing value
    # that was set.  We also set the "sort_keys" value.
    if current_app.debug:
        settings.setdefault('indent', 4)
        settings.setdefault('sort_keys', not PY3)

    # always end the json dumps with a new line
    # see https://github.com/mitsuhiko/flask/pull/1262
    dumped = dumps(data, **settings) + "\n"

    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp


class LoginResource(Resource):

    def post(self):

        from flask_restful import reqparse
        # 创建一个 RequestParser 实例
        parse = reqparse.RequestParser()
        # 添加参数
        from flask_restful import inputs
        parse.add_argument('mobile', location='json', required=True, type=inputs.regex('^1[3-9][0-9]{9}$'))
        parse.add_argument('code', location='json', required=True)

        # 验证数据
        args = parse.parse_args()
        mobile = args.get('mobile')
        code = args.get('code')

        current_app.logger.info(code)

        # 3.判断手机号是否有注册
        user = None
        try:
            user = User.query.filter_by(mobile=mobile).first()
        except Exception as e:
            current_app.logger.error(e)

        if user:
            # 已注册
            user.last_login = datetime.now()
            db.session.commit()
        else:
            # 未注册
            user = User()
            user.mobile = mobile
            user.name = mobile
            user.last_login = datetime.now()
            db.session.add(user)
            db.session.commit()

        # 4.状态保持 生成token
        token = login_token(user.id)

        # 5.返回响应
        return {'token': token}


class SmsCodeResource(Resource):

    def get(self,mobile):

        # 发送短信逻辑: 生成一个随机码 保存到 redis 中, 并设置一个时间
        smscode = randint(100000,999999)

        current_app.redis_store.setex(mobile, 60, smscode)

        return {'mobile': mobile}


from project.utils.user import loginrequired


class CenterResource(Resource):

    method_decorators = [loginrequired]

    def get(self):

        # # 1.request.headers 获取 token
        # authorization = request.headers.get('Authorization')
        # # Bearer eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Nzc3OTU0MywiZXhwIjoxNTc4Mzg0MzQzfQ.eyJ1c2VyX2lkIjoxfQ.knbtJwJGbLC8pXuF4BiK4bwEcEa4s-lVO0cSc0cdzQc2r4tiYMTaJ5N2KLcsd7q-FESVEcKzS7so-5X2muVwpw
        # if authorization is not None and authorization.startswith('Bearer'):
        #     token = authorization[7:]
        #     # 2.验证token
        #     user_id = check_user_token(token)
        # 3.根据 user_id 进行数据的查询
        # if g.user_id:
        #     user = None

        try:
            user = User.query.get(g.user_id)
        except Exception as e:
            current_app.logger.error(e)

        else:
            # 4.返回响应
            return {
                'mobile': user.mobile,
                'name': user.name,
                'profile_photo': user.profile_photo,
                "intro": user.introduction,
                "art_count": user.article_count,
                "follow_count": user.following_count,
                "fans_count": user.fans_count
            }


class UserChannelResource(Resource):

    method_decorators = [loginrequired]

    def get(self):

        # 1.获取用户id
        user_id = g.user_id
        # 2.根据用户id进行频道的查询
        channels = UserChannel.query.filter(
            UserChannel.user_id==user_id
        ).all()
        # 3.将列表数据转换为字典
        channels_list = []
        for item in channels_list:
            channels_list.append({
                'id': item.id,
                'name': item.channel.name
            })

        return {'channels': channels_list}

    def put(self):

        user_id = g.user_id

        # 1.接收数据, 并且验证数据(省略)
        channels = request.json.get('channels')
        # 2.把当前用户已经添加的频道全部标记为 已删除
        # filter_by().update({key: value})
        # UserChannel.query.filter(UserChannel.user_id==user_id).update(is_deleted=True)
        UserChannel.query.filter(UserChannel.user_id==user_id).update({'is_deleted': True})
        db.session.commit()
        # 3.将前端传递过来的频道进行遍历.如果存在频道则进行更新,未存在则进行新增
        for channel in channels:
            # {'seq': xxx, 'channel_id': xxx}
            flag = UserChannel.query.filter(
                UserChannel.user_id==user_id,
                UserChannel.channel_id==channel.get('channel_id')
            ).update({
                'sequence': channel.get('seq'),
                'is_deleted': False
            })

            if flag:
                db.session.commit()
            else:
                # 插入一条新数据
                new_user_channel = UserChannel()
                new_user_channel.user_id = user_id
                new_user_channel.channel_id = channel.get('channel_id')
                new_user_channel.is_deleted = False
                new_user_channel.sequence = channel.get('seq')

                db.session.add(new_user_channel)
                db.session.commit()

        return {'msg': 'ok'}


user_api.add_resource(LoginResource, '/authorizations')
user_api.add_resource(CenterResource, '/user')
user_api.add_resource(SmsCodeResource, '/sms/codes/<mobile>/')
user_api.add_resource(UserChannelResource, '/user/channels')